package org.wattdepot.gdata.kukuicup;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.wattdepot.gdata.kukuicup.service.GDataService;
import org.wattdepot.gdata.kukuicup.service.WattDepotService;
import org.wattdepot.gdata.kukuicup.updater.Updater;

/**
 * The main class for the GData updater process. 
 * 
 * First, it reads in a properties file that provides the
 * WattDepot server, the GData credentials, and which updaters to run. Execution terminates if
 * problems are found during this initialization process.
 * 
 * Second, it creates instances of updaters based upon the properties file and gets them running.
 * @author Philip Johnson
 */
public class Main {
  
  private List<Updater> updaters = new ArrayList<Updater>();
  
  /**
   * The main program that accepts an optional properties file and uses it to initialize the 
   * system. 
   * @param args Provides the properties file name, or defaults to kukuicup.gdata.properties.
   * @throws Exception If problems occur.
   */
  public static void main(String[] args) throws Exception {
    String propertiesFileName = (args.length == 0) ? "kukuicup.gdata.properties" : args[0];
    System.out.println("Kukui Cup GData services starting up.");
    GDataProperties properties = new GDataProperties(propertiesFileName);
  
    Main theMain = new Main(properties);
    
    System.out.println("All enabled services have been started. Press return to quit.");
    // Now wait for keyboard input indicating that execution should terminate.
    while (System.in.available() == 0) {
      Thread.sleep(2000);
    }
    System.out.println("Stopping Kukui Cup GData services...");
    // Exit gracefully.
    theMain.cancel();
    System.out.println("Kukui Cup GData services terminated.");
  }
    
  
  /**
   * Initializes the WattDepot and GData services, then instantiates updaters depending upon 
   * properties file specifications. 
   * @param properties The property file to use. 
   * @throws Exception If problems occur.
   */
  public Main(GDataProperties properties) throws Exception {
    WattDepotService wattDepotService = new WattDepotService(properties);
    GDataService gdataService = new GDataService(properties);
    // Now kick off all of the enabled updater tasks. 
    for (String updaterClassName : properties.getEnabledUpdaterClassNames()) {
      System.out.println("Instantiating updater: " + updaterClassName);
      // Define the two arg constructor information
      Class<?>[] argsClass = new Class[] { WattDepotService.class, GDataService.class };
      Object[] args = new Object[] { wattDepotService, gdataService };
      // Get the class associated with the classname string
      Class<?> theClass = Class.forName(updaterClassName);
      // Get the constructor that accepts these two args.
      Constructor<?> constructor = theClass.getConstructor(argsClass);
      Updater updater = (Updater)constructor.newInstance(args);
      this.updaters.add(updater);
      updater.run();
    }
  }
  
  /**
   * Invokes the cancel method on all enabled updaters. 
   */
  private void cancel() {
    for (Updater updater : updaters) {
      updater.cancel();
    }
  }
  

}
